package hygprs

/*
用来注册并订阅的包
具体数据

	预置角色 一个字节
	要订阅的包类型 格式待定 没有时可以为空
*/
type InternalRegister struct {
	base
}

func (e *InternalRegister) Load(data []byte) (reason string, ok bool) {
	if len(data) < 13 {
		return "数据格式错误", false
	}
	e.data = data
	return "", true
}

func (e *InternalRegister) GetRole() Role {
	return Role(e.data[7])
}

func (e *InternalRegister) SetRole(v Role) {
	e.data[7] = byte(v)
}

func (e *InternalRegister) Make(r Role) []byte {
	data := make([]byte, 0, 13)
	data = append(data, Internal, 0, 13, 2, 0, 0, PackageRegister, byte(r))
	data = append(data, FromUint32(CheckSum(data))...)
	data = append(data, Internal+1)
	return data
}

/*
用来包装要转发的数据的包
除了来自车载端的数据，可以以车号作为标志之外，其他来源的数据，转发时需要记录ip地址作为标志，从而在收到回应时可以转发给原来的来源
具体数据

	是否是回应 一个字节
	转发表长度 一个字节
	转发表 每一条6个字节*转发表长度
	转发的内容
*/
type InternalForward struct {
	base
	count int
}

func (e *InternalForward) Load(data []byte) (reason string, ok bool) {
	if len(data) < 14 {
		return "数据格式错误", false
	}
	e.count = int(data[8])
	if len(data) < 14+e.count*6 {
		return "数据格式错误", false
	}
	e.data = data
	return "", true
}

func (e *InternalForward) IsReply() bool {
	return e.data[7] != 0
}

func (e *InternalForward) GetCount() int {
	return int(e.data[8])
}

func (e *InternalForward) GetList() (list []string) {
	for i := 0; i < int(e.data[8]); i++ {
		list = append(list, ToIPAddr(e.data[9+6*i:15+6*i]))
	}
	return
}

func (e *InternalForward) GetContent() []byte {
	return e.data[9+6*int(e.data[8]) : len(e.data)+PositionChecksum]
}

func (*InternalForward) MakeForward(data []byte, list []string, addr string) []byte {
	list = append([]string{addr}, list...)
	l := 14 + 6*len(list) + len(data)
	res := make([]byte, 0, l)
	res = append(res, Internal)
	res = append(res, FromUint16(uint16(l))...)
	res = append(res, 0x02, 0x00, 0x00, PackageForward, 0, byte(len(list)))
	for _, a := range list {
		res = append(res, FromIPAddr(a)...)
	}
	res = append(res, data...)
	res = append(res, FromUint32(CheckSum(res))...)
	res = append(res, Internal+1)
	return res
}

func (*InternalForward) MakeReply(data []byte, list []string) []byte {
	l := 14 + 6*len(list) + len(data)
	res := make([]byte, 0, l)
	res = append(res, Internal)
	res = append(res, FromUint16(uint16(l))...)
	res = append(res, 0x02, 0x00, 0x00, PackageForward, 1, byte(len(list)))
	for _, a := range list {
		res = append(res, FromIPAddr(a)...)
	}
	res = append(res, data...)
	res = append(res, FromUint32(CheckSum(res))...)
	res = append(res, Internal+1)
	return res
}

func (e *InternalForward) Pop() (data []byte, addr string) {
	list := e.GetList()
	content := e.GetContent()
	if len(list) > 1 {
		return e.MakeReply(content, list[1:]), list[0]
	} else {
		return content, list[0]
	}
}
